package com.lijie.ljblog.socketAPI;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lijie.ljblog.chess.Chess;
import com.lijie.ljblog.chess.ChessGameRoom;
import com.lijie.ljblog.chess.ChessPoint;
import com.lijie.ljblog.enums.ChessColorEnum;
import com.lijie.ljblog.model.vo.ChessResponseVO;
import com.lijie.ljblog.util.GoBangBotUtil;
import com.lijie.ljblog.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @Description 人机对战webSocket
 * @Author lijie
 * @Date 2022/8/26 16:32
 **/
@Slf4j
@Component
public class PVEGameAPI extends TextWebSocketHandler {
    private ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 用户房间
     */
    private Map<Integer,ChessGameRoom> gameRoomMap =new ConcurrentHashMap<>();

    /**
     * 用户会话
     */
    private Map<Integer,WebSocketSession> userSessionMap =new ConcurrentHashMap<>();

    /**
     * 建立连接，初始化一个游戏房间
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        Integer userId = GoBangBotUtil.getUserId(session);

        if(userSessionMap.get(userId)!=null){
            //当前改用户已经存在连接，不能多开
            Result<String> result = new Result<>();
            result.setErrored("游戏不能多开");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(result)));
        }else{
            //用户第一次连接，初始化游戏房间和用户会话
            ChessGameRoom chessGameRoom = new ChessGameRoom();
//            chessGameRoom.setBlackPerson(userId);
            gameRoomMap.put(userId,chessGameRoom);
            userSessionMap.put(userId,session);
        }
    }

    /**
     * 玩家落子
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        Integer userId = GoBangBotUtil.getUserId(session);
        //通过userId获取游戏房间
        ChessGameRoom chessGameRoom = gameRoomMap.get(userId);
        ChessPoint chessPoint = JSON.parseObject(message.getPayload(), ChessPoint.class);
        int[][] chessBoard = chessGameRoom.getChess().getChessBoard();
        if(chessBoard[chessPoint.getX()][chessPoint.getY()] != 0){
            log.error("该处不能落子");
            return;
        }
        //获得当前游戏棋盘
        Chess chess = chessGameRoom.getChess();
        //玩家落子
        chess.putChess(ChessColorEnum.CHESS_POINT_BLACK,chessPoint.getX(),chessPoint.getY());
        //返回前端
        ChessResponseVO chessResponseVO = new ChessResponseVO(chessPoint.getX(),chessPoint.getY(),ChessColorEnum.CHESS_POINT_BLACK);
        //判断游戏是否结束
        boolean b = chess.checkWinner(ChessColorEnum.CHESS_POINT_BLACK, chessPoint.getX(), chessPoint.getY());
        if(b){
            //玩家赢了
            chessResponseVO.setWinnerUserId(userId);
            //销毁房间
            gameRoomMap.remove(userId);
            //返回前端数据：玩家赢了
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(chessResponseVO)));
        }else{
            //没有结束，返回前端 玩家的落子
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(chessResponseVO)));

            //电脑计算位置
            ChessPoint aiChessPoint = chess.AiChesser(ChessColorEnum.CHESS_POINT_WHITE.getVal());
            //电脑落子
            chess.putChess(ChessColorEnum.CHESS_POINT_WHITE,aiChessPoint.getX(),aiChessPoint.getY());
            ChessResponseVO aichessResponseVO = new ChessResponseVO(aiChessPoint.getX(),aiChessPoint.getY(),ChessColorEnum.CHESS_POINT_WHITE);
            //判断游戏是否结束
            boolean aiB = chess.checkWinner(ChessColorEnum.CHESS_POINT_WHITE, aiChessPoint.getX(), aiChessPoint.getY());
            if(aiB){
                //电脑赢了
                aichessResponseVO.setWinnerUserId(-1);
                //销毁房间
                gameRoomMap.remove(userId);
            }
            //返回前端
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(aichessResponseVO)));
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
    }

    /**
     * 用户关闭连接，删除用户游戏房间和用户会话
     * @param session
     * @param status
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        Integer userId = GoBangBotUtil.getUserId(session);
        userSessionMap.remove(userId);
        gameRoomMap.remove(userId);
    }
}
